home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / ov143b.zip / CVTHLP.C < prev    next >
C/C++ Source or Header  |  1993-01-04  |  12KB  |  404 lines

  1. /*  004  12-Jan-87  cvthlp.c
  2.  
  3.         This program converts a text help file to "compiled" format
  4.         used by OverView.
  5.  
  6.         Copyright (c) 1987 by Blue Sky Software.  All rights reserved.
  7. */
  8.  
  9. #define VERSION "Cvthlp 1.01 12-Jan-87"
  10.  
  11. #include <stdio.h>
  12. #include <fcntl.h>
  13.  
  14. unsigned long offset = 0;
  15.  
  16. char inbuf[4096], outbuf[4096];
  17.  
  18. int verbose = 0;
  19. FILE *inf, *outf;
  20. char line[81], *infile, *outfile;
  21.  
  22. #define TXTLINES 24
  23. #define MENUENTS 20
  24.  
  25. unsigned char nmenu, ntext;
  26. char menuent[MENUENTS][81], textlin[TXTLINES][81], header[81];
  27.  
  28. char *strchr();
  29. long ftell(), findframe();
  30.  
  31.  
  32. /******************************************************************************
  33.                                 M A I N
  34.  *****************************************************************************/
  35.  
  36. main(argc,argv)
  37. int argc;
  38. char **argv;
  39. {
  40.    /* process the command line arguments */
  41.  
  42.    do_args(argc,argv);
  43.  
  44.    /* assume user does't know what he is doing if I/O is to/from tty */
  45.  
  46.    if (isatty(fileno(inf)) || isatty(fileno(outf)))
  47.       usage();
  48.  
  49.    setmode(fileno(outf),O_BINARY);     /* need binary mode on output */
  50.  
  51.    /* use big buffers size for in/out files */
  52.  
  53.    setvbuf(inf,inbuf,_IOFBF,sizeof(inbuf));
  54.    setvbuf(outf,outbuf,_IOFBF,sizeof(outbuf));
  55.  
  56.    /* convert the file */
  57.  
  58.    pass1();                    /* pass 1, transform text file to frame fmt */
  59.  
  60.    fclose(inf);                /* close pass 1 files */
  61.    fclose(outf);
  62.  
  63.    if ((outf = fopen(outfile,"r+")) == NULL) {
  64.       perror("Can't reopen out file");
  65.       exit(2);
  66.    }
  67.  
  68.    setmode(fileno(outf),O_BINARY);             /* need binary mode on output */
  69.    setvbuf(outf,outbuf,_IOFBF,sizeof(outbuf)); /* use a big buffer */
  70.  
  71.    pass2();                    /* pass 2, fixup offsets in output file */
  72.  
  73.    fclose(outf);
  74. }
  75.  
  76.  
  77. /******************************************************************************
  78.                                 P A S S 1
  79.  ******************************************************************************/
  80.  
  81. static int
  82. pass1() {              /* transform text help file to frame format */
  83.  
  84.    int i;
  85.  
  86.    *line = ' ';                /* force an initial file read */
  87.  
  88.    while (read_txt_frame()) {
  89.  
  90.       /* write the help frame data to the output file */
  91.  
  92.       fputs(header,outf);              /* output the frame header line */
  93.  
  94.       fputc(nmenu,outf);               /* # menu entries */
  95.  
  96.       for (i = 0; i < nmenu; i++) {    /* do all menu entries */
  97.          fwrite(&offset,sizeof(offset),1,outf);    /* offset to ent's frame */
  98.          fputs(menuent[i],outf);                   /* keyword/prompt string */
  99.       }
  100.  
  101.       fputc(ntext,outf);               /* # text lines */
  102.  
  103.       for (i = 0; i < ntext; i++)      /* do all text lines */
  104.          fputs(textlin[i],outf);
  105.    }
  106. }
  107.  
  108.  
  109. /******************************************************************************
  110.                       R E A D _ T X T _ F R A M E
  111.  ******************************************************************************/
  112.  
  113. static int
  114. read_txt_frame() {            /* read a text help frame */
  115.  
  116.    if (feof(inf))
  117.       return(0);
  118.  
  119.    if (*line != '#')                       /* read till next header line */
  120.       while (readlin() && *line != '#')    /* (doesn't read if already there */
  121.          if (verbose)
  122.             fprintf(stderr,"Skipping: %s\n",line);
  123.  
  124.    if (*line == '#') {
  125.       strcpy(header,line);             /* save header line less # */
  126.  
  127.       if (verbose)
  128.          fprintf(stderr,"Header: %s",header);
  129.  
  130.       /* read the text and menu segments */
  131.  
  132.       nmenu = ntext = 0;
  133.  
  134.       readlin();
  135.  
  136.       if (strnicmp(line,"TEXT",4) == 0) {
  137.          read_txt_text();
  138.          readlin();
  139.       }
  140.  
  141.       if (strnicmp(line,"MENU",4) == 0) {
  142.          read_txt_menu();
  143.          readlin();
  144.       }
  145.  
  146.       if (nmenu == 0 && ntext == 0)
  147.          fprintf(stderr,"No menu or text section for %s",header);
  148.  
  149.       return(1);
  150.    }
  151.  
  152.    return(0);
  153. }
  154.  
  155.  
  156. /*****************************************************************************
  157.                           R E A D _ T X T _ T E X T
  158.  *****************************************************************************/
  159.  
  160. static int
  161. read_txt_text() {      /* read text section */
  162.  
  163.    while (readlin() && strnicmp(line,"TXET",4) != 0 && ntext < TXTLINES)
  164.       strcpy(textlin[ntext++],line);
  165.  
  166.    if (ntext == TXTLINES && strnicmp(line,"TXET",4) != 0) {
  167.       fprintf(stderr,"More than %d lines of text for %s",TXTLINES,header);
  168.       while (readlin() && strnicmp(line,"TXET",4) != 0)
  169.          ;
  170.    }
  171. }
  172.  
  173.  
  174. /*****************************************************************************
  175.                         R E A D _ T X T _ M E N U
  176.  *****************************************************************************/
  177.  
  178. static int
  179. read_txt_menu() {      /* read menu section */
  180.  
  181.    while (readlin() && strnicmp(line,"UNEM",4) != 0 && nmenu < MENUENTS)
  182.       strcpy(menuent[nmenu++],line);
  183.  
  184.    if (nmenu == MENUENTS && strnicmp(line,"UNEM",4) != 0) {
  185.       fprintf("More than %d menu entries for %s",MENUENTS,header);
  186.       while (readlin() && strnicmp(line,"UNEM",4) != 0)
  187.          ;
  188.    }
  189. }
  190.  
  191.  
  192. /******************************************************************************
  193.                               R E A D L I N
  194.  ******************************************************************************/
  195.  
  196. static int
  197. readlin() {            /* read a line */
  198.  
  199.    char buf[512];
  200.  
  201.    if (fgets(buf,sizeof(buf),inf)) {
  202.       if (strlen(buf) > 80) {
  203.          buf[81] = '\0';
  204.          if (verbose)
  205.             fprintf(stderr,"Truncated: %.65s\n",buf);
  206.       }
  207.       strcpy(line,buf);
  208.       return(1);
  209.    }
  210.  
  211.    return(0);
  212. }
  213.  
  214.  
  215. /******************************************************************************
  216.                                 P A S S 2
  217.  ******************************************************************************/
  218.  
  219. static int
  220. pass2() {              /* reread the frame file and fixup the frame offsets */
  221.  
  222.    while (fixframe())          /* fixup all the help frames */
  223.       ;
  224. }
  225.  
  226.  
  227. /******************************************************************************
  228.                              F I X F R A M E
  229.  ******************************************************************************/
  230.  
  231. static int
  232. fixframe() {           /* fixup the current help frame */
  233.  
  234.    unsigned long offsetloc, frameloc;
  235.  
  236.    if (fgets(header,sizeof(header),outf) == NULL)    /* get frame header */
  237.       return(0);                                     /* done if EOF */
  238.  
  239.    nmenu = fgetc(outf);                /* get # menu entries */
  240.  
  241.    while (nmenu--) {
  242.  
  243.       offsetloc = ftell(outf);         /* this is the loc to fixup */
  244.  
  245.       fread(&frameloc,sizeof(frameloc),1,outf);  /* read dummy offset */
  246.       fgets(line,sizeof(line),outf);   /* read menu item */
  247.  
  248.       frameloc = findframe();          /* find the frame for this menu item */
  249.  
  250.       fseek(outf,offsetloc,SEEK_SET);  /* back to the menu offset location */
  251.  
  252.       fwrite(&frameloc,sizeof(frameloc),1,outf);    /* offset to ent's frame */
  253.  
  254.       fseek(outf,0L,SEEK_CUR);         /* seek nowhere just so we can read */
  255.  
  256.       fgets(line,sizeof(line),outf);   /* reread current menu item */
  257.    }
  258.  
  259.    /* just skip over the text lines to find next frame */
  260.  
  261.    skip_txt();
  262.  
  263.    return(1);                  /* another frame processed */
  264. }
  265.  
  266.  
  267. /******************************************************************************
  268.                            F I N D F R A M E
  269.  ******************************************************************************/
  270.  
  271. static long
  272. findframe() {          /* find the frame whose name is in line */
  273.  
  274.    int nummenu;
  275.    long frameloc;
  276.    char *cp, name[81];
  277.  
  278.    if (cp = strchr(line,' ')) {        /* isolate frame name from menu line */
  279.       *name = '\0';
  280.       strncat(name,line,cp-line);
  281.    } else {
  282.       fprintf(stderr,"Bad menu ent in findframe: %s\n",line);
  283.       exit(2);
  284.    }
  285.  
  286.    /* skip to the end of the current frame */
  287.  
  288.    nummenu = nmenu;
  289.    while (nummenu--) {
  290.       fread(&frameloc,sizeof(frameloc),1,outf);   /* skip over offset */
  291.       fgets(line,sizeof(line),outf);              /* skip over keyword/prompt */
  292.    }
  293.  
  294.    skip_txt();         /* skip over text lines */
  295.  
  296.    while (1) {         /* now find the desired frame */
  297.  
  298.       frameloc = ftell(outf);                  /* this may be the one */
  299.  
  300.       if (fgets(line,sizeof(line),outf) == NULL) {   /* error if EOF */
  301.          fprintf(stderr,"Unable to find frame %s\n",name);
  302.          exit(2);
  303.       }
  304.  
  305.       if (*line != '#') {              /* make sure were at a frame start */
  306.          fprintf(stderr,"Not start of frame: %s\n",line);
  307.          exit(2);
  308.       }
  309.  
  310.       if (strnicmp(name,line+1,strlen(name)) == 0)      /* is this the one? */
  311.          return(frameloc);                              /* yes, return offset */
  312.  
  313.       /* not the one, skip to the next one */
  314.  
  315.       nummenu = fgetc(outf);
  316.       while (nummenu--) {
  317.          fread(&frameloc,sizeof(frameloc),1,outf);   /* skip offset */
  318.          fgets(line,sizeof(line),outf);              /* skip keyword/prompt */
  319.       }
  320.  
  321.       skip_txt();         /* skip over text lines */
  322.    }
  323. }
  324.  
  325.  
  326. /*****************************************************************************
  327.                             S K I P _ T X T
  328.  *****************************************************************************/
  329.  
  330. static int
  331. skip_txt() {           /* skip over a frame's text lines */
  332.  
  333.    int numtext;
  334.  
  335.    numtext = fgetc(outf);
  336.    while (numtext--)
  337.       fgets(line,sizeof(line),outf);
  338. }
  339.  
  340.  
  341. /******************************************************************************
  342.                                D O _ A R G S
  343.  ******************************************************************************/
  344.  
  345. static int
  346. do_args(argc,argv)     /* process the command line arguments */
  347. int argc;
  348. char **argv;
  349. {
  350.    int c;
  351.    extern char *optarg;
  352.    extern int optind;
  353.  
  354.    while ((c = getopt(argc,argv,"v")) != EOF)
  355.       switch (c) {
  356.          case 'v':
  357.             verbose++;
  358.             break;
  359.          default:
  360.             usage();
  361.             break;
  362.       }
  363.  
  364.    if (optind < argc) {                 /* next arg is input file name */
  365.       if ((inf = fopen(infile = argv[optind],"r")) == NULL) {
  366.          perror("Unable to open input file");
  367.          exit(2);
  368.       }
  369.       optind++;
  370.  
  371.    } else              /* input file name was not given */
  372.       usage();
  373.  
  374.    if (optind < argc) {                 /* next arg is output file name */
  375.       if ((outf = fopen(outfile = argv[optind],"w")) == NULL) {
  376.          perror("Unable to open output file");
  377.          exit(2);
  378.       }
  379.       optind++;
  380.  
  381.    } else              /* output file name was not given */
  382.       usage();
  383.  
  384.    if (optind < argc)  /* better not be any more arguments */
  385.       usage();
  386. }
  387.  
  388.  
  389. /*****************************************************************************
  390.                                U S A G E
  391.  *****************************************************************************/
  392.  
  393. static int
  394. usage() {              /* tell user how to use program */
  395.  
  396.    fputs("\nUsage:  cvthlp [-v] in_file out_file\n\n",stderr);
  397.  
  398.    fputs("Where: -v turns on verbose messages.\n",stderr);
  399.    fputs("       in_file is the name of the help file to be converted\n",stderr);
  400.    fputs("       out_file is name to give the converted help file\n",stderr);
  401.  
  402.    exit(2);
  403. }
  404.